/*
 * 因为正式环境签名一分钟就会过期，所以每次请求之前主动重新向app获取签名，如果
 * 有需求是在app内部不用token就可以获取数据的接口，请求的时候把flag设置成true,
 * 这样不用传token也能正常获取数据
 *
 * */


import axios from 'axios';
import {
    Toast
} from 'vant';
import {
    isApp,
    isAndroid,
    getParamsFromUrl,
    getUaData,
    getHxsAppVersion,
    compareAppVersion
} from './common'

/*
 * 因为正式环境签名一分钟就会过期，所以每次请求之前主动重新向app获取签名，如果
 * 有需求是在app内部不用token就可以获取数据的接口，请求的时候把flag设置成true,
 * 这样不用传token也能正常获取数据
 *
 * */
/*"hxs-gin-dev"//*/
const getBaseArg = () => {
    return {
        sess_token: getParamsFromUrl('sess_token') || getUaData('sess_token'),
        utime: getParamsFromUrl('utime') || getUaData('utime'),
        sign: decodeURIComponent(getParamsFromUrl('sign') || getUaData('sign'))
            // sign: "hxs-gin-dev"
    }
};


/*先进先出*/
const funcs = [];

function getUserInfo(flag) {
    return new Promise((resolve, reject) => {
        let base = getBaseArg();
        if (isApp()) {
            window.hxsappPlusGetUserAgent = (data) => {

                const { func1, func2 } = funcs.shift();

                if (data) {
                    if (isAndroid()) {
                        const query = new URLSearchParams(data);
                        if (query.get('sess_token')) {
                            base = {
                                sess_token: query.get('sess_token'),
                                utime: query.get('utime'),
                                sign: decodeURIComponent(query.get('sign'))
                            };

                            func1(base)
                        } else {
                            if (flag) {
                                func1(base);
                            } else {
                                window.location.href = 'https://hxsapp_showloginpage';
                                func2(401);
                            }
                        }

                    } else {


                        const query = data;
                        if (query['sess_token']) {
                            base = {
                                sess_token: query['sess_token'],
                                utime: query['utime'],
                                sign: decodeURIComponent(query['sign'])
                            };

                            func1(base);

                        } else {
                            if (flag) {
                                func1(base);
                            } else {
                                window.location.href = 'https://hxsapp_showloginpage';
                                func2(401);
                            }
                        }
                    }
                } else {

                    if (flag) {
                        func1(base);
                    } else {
                        window.location.href = 'https://hxsapp_showloginpage';
                        func2(401);
                    }
                }
            }
            funcs.push({
                func1: resolve,
                func2: reject
            })
            if (isAndroid()) {
                window.TokenJsInterface && window.TokenJsInterface.getData('');
            } else {
                window.webkit.messageHandlers.TokenJsInterface && window.webkit.messageHandlers.TokenJsInterface.postMessage('');
            }
        } else {
            if (flag) {
                resolve(base);
            } else {
                reject(401);
            }

        }

    })
}


function sendRequest(type, url, params, flag, headers, warning, responseType = '', all = false) {

    return new Promise((resolve, reject) => {
        getUserInfo(flag).then(info => {
            if (info === 401) {
                return reject(info);
            }

            if (type === 'GET') {
                return axios.get(url, {
                    params: {
                        ...info,
                        ...params,
                        _: Date.now()
                    },
                    headers: {
                        /*'Cache-Control': 'no-cache',*/
                        ...headers

                    },
                    responseType: responseType
                })
            } else if (type === 'POST') {
                return axios.post(url, {
                    ...info,
                    ...params,
                    _: Date.now()
                }, {
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                        /*'Cache-Control': 'no-cache',*/
                        ...headers

                    },
                    transformRequest: [data => {
                        return $stringify(data)
                    }]
                })
            }
        }).then(res => {
            let {
                code,
                msg
            } = res.data;
            if (all) return resolve(res.data);
            if (String(code) === '401') {
                return reject(401);
            }
            if (String(code) !== '200') {
                if (warning) {
                    Toast(msg || 'API 接口出错!');
                }
                reject(res.data);
            } else {
                resolve(res.data);
            }
        }).catch(e => {
            if (e !== 401) {
                Toast(e.message || '数据请求失败!');
            }
            reject(e);
        })
    })

}

function getAppInfo(flag) {
    return new Promise((resolve, reject) => {
        let base = getBaseArg();
        if (isApp()) {
            window.getAppInfoCallback = (data) => {
                if (data) {
                    if (isAndroid()) {
                        const query = new URLSearchParams(data);
                        if (query.get('sess_token')) {
                            base = {
                                sess_token: query.get('sess_token'),
                                utime: query.get('utime'),
                                sign: decodeURIComponent(query.get('sign'))
                            };
                            resolve(base)
                        } else {
                            if (flag) {
                                resolve(base);
                            } else {
                                window.location.href = 'https://hxsapp_showloginpage';
                                reject(401);
                            }
                        }

                    } else {
                        const query = data;
                        if (query['sess_token']) {
                            base = {
                                sess_token: query['sess_token'],
                                utime: query['utime'],
                                sign: decodeURIComponent(query['sign'])
                            };
                            resolve(base);
                        } else {
                            if (flag) {
                                resolve(base);
                            } else {
                                window.location.href = 'https://hxsapp_showloginpage';
                                reject(401);
                            }
                        }
                    }
                } else {
                    if (flag) {
                        resolve(base);
                    } else {
                        window.location.href = 'https://hxsapp_showloginpage';
                        reject(401);
                    }
                }
            };
            /*获取token*/
            window.location.href = 'https://hxsapp_get_app_info?func=getAppInfoCallback';
            /*setTimeout(() => {
                window.location.href = 'https://hxsapp_get_app_info?func=getAppInfoCallback';
            }, 100);*/
        } else {
            resolve(base);
        }
    });

}

const funcArr = [];
let tag = false;


function postProcessor(type, url, params, flag, headers, warning, responseType = '', all = false) {
    return new Promise((resolve, reject) => {
        funcArr.push({
            func: getAppInfo,
            type,
            url,
            params,
            flag,
            headers,
            all,
            resolve,
            reject,
            warning,
            responseType
        });

        function next() {
            const info = funcArr.shift();
            if (info) {
                const {
                    func,
                    type,
                    url,
                    params,
                    flag,
                    headers,
                    all,
                    resolve,
                    reject,
                    warning
                } = info;
                func(flag).then(res => {
                    if (res === 401) {
                        return Promise.reject(res);
                    }
                    if (type === 'GET') {
                        return axios.get(url, {
                            params: {
                                ...res,
                                ...params,
                                _: Date.now()
                            },
                            headers: {
                                /*'Cache-Control': 'no-cache',*/
                                ...headers

                            },
                            responseType: responseType
                        })
                    } else if (type === 'POST') {
                        return axios.post(url, {
                            ...res,
                            ...params,
                            _: Date.now()
                        }, {
                            headers: {
                                'Content-Type': 'application/x-www-form-urlencoded',
                                /*'Cache-Control': 'no-cache',*/
                                ...headers

                            },
                            transformRequest: [data => {
                                return $stringify(data)
                            }]
                        })
                    }

                }).then(response => {
                    let {
                        code,
                        msg
                    } = response.data;
                    if (all) return resolve(response.data);
                    if (String(code) === '401') {
                        return reject(401);
                    }
                    if (String(code) !== '200') {
                        if (warning) {
                            Toast(msg || 'API 接口出错!');
                        }
                        reject(response.data);
                    } else {
                        resolve(response.data);
                    }
                }).catch(e => {
                    if (e !== 401) {
                        Toast(e.message || '数据请求失败!');
                    }
                    reject(e);
                }).finally(() => {

                    tag = false;
                    next(resolve, reject);
                });
            }
        }

        if (!tag) {
            tag = true;
            next()
        }
    })
}

function $stringify(params) {
    let query = [];
    for (let key in params) {
        query.push(key + '=' + params[key])
    }
    return query.join('&');
}

export default {
    // 因参数问题，暂不做抽取
    get: function(url, params = {}, flag = false, headers = {}, warning = true) {
        if (compareAppVersion(getHxsAppVersion(), '7.4.9')) {
            return sendRequest('GET', url, params, flag, headers, warning);
        } else {
            return postProcessor('GET', url, params, flag, headers, warning)
        }
    },
    post: function(url, data = {}, flag = false, headers = {}, warning = true) {
        if (compareAppVersion(getHxsAppVersion(), '7.4.9')) {
            return sendRequest('POST', url, data, flag, headers, warning);
        } else {
            return postProcessor('POST', url, data, flag, headers, warning);
        }
    },
    getDownload: function(url, params = {}, flag = false, headers = {}, warning = true) {
        return postProcessor('GET', url, params, flag, headers, warning, 'arraybuffer', true)
    },
    getAll: function(url, params = {}, flag = false, headers = {}) {
        return postProcessor('GET', url, params, flag, headers, true)
    },
    postAll: function(url, data = {}, flag = false, headers = {}) {
        return postProcessor('POST', url, data, flag, headers, true);
    }
}